home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Resources / Online / Term / Extras / Source / term-source.lha / DialList.c < prev    next >
C/C++ Source or Header  |  1996-10-20  |  14KB  |  670 lines

  1. /*
  2. **    DialList.c
  3. **
  4. **    Dial list support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. **    :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16. VOID
  17. ToggleDialEntry(PhonebookHandle *PhoneHandle,PhoneEntry *Entry)
  18. {
  19.     if(Entry->Count < 0)
  20.         MarkDialEntry(PhoneHandle,Entry);
  21.     else
  22.         UnmarkDialEntry(PhoneHandle,Entry);
  23. }
  24.  
  25. VOID
  26. MarkDialEntry(PhonebookHandle *PhoneHandle,PhoneEntry *Entry)
  27. {
  28.     if(Entry->Count < 0 && Entry->Header->Number[0] && Entry->Header->Name[0])
  29.     {
  30.             /* Another entry for the dial list */
  31.  
  32.         Entry->Count = PhoneHandle->DialMarker++;
  33.  
  34.             /* Update the name */
  35.  
  36.         UpdatePhoneNode(Entry->Node);
  37.     }
  38. }
  39.  
  40. VOID
  41. UnmarkDialEntry(PhonebookHandle *PhoneHandle,PhoneEntry *Entry)
  42. {
  43.     if(Entry && Entry->Count >= 0)
  44.     {
  45.         struct PhoneEntry **Phonebook = PhoneHandle->Phonebook;
  46.         LONG Count = Entry->Count,i;
  47.  
  48.             /* Update all phonebook entries to show the order in which */
  49.             /* entries are to go into the dial list */
  50.  
  51.         for(i = 0 ; i < PhoneHandle->NumPhoneEntries ; i++)
  52.         {
  53.             if(Phonebook[i]->Count > Count)
  54.             {
  55.                     /* Decrement the index if it's larger than the one */
  56.                     /* to be removed */
  57.  
  58.                 Phonebook[i]->Count--;
  59.  
  60.                     /* Update the name. */
  61.  
  62.                 UpdatePhoneNode(Phonebook[i]->Node);
  63.             }
  64.         }
  65.  
  66.             /* Reset the index; this entry is not to go into the dial list */
  67.  
  68.         Entry->Count = -1;
  69.  
  70.             /* Update the name */
  71.  
  72.         UpdatePhoneNode(Entry->Node);
  73.  
  74.             /* One entry less to go into the dial list */
  75.  
  76.         PhoneHandle->DialMarker--;
  77.     }
  78. }
  79.  
  80. /****************************************************************************/
  81.  
  82. STATIC struct DialNode *
  83. FindNumberInDialList(struct List *List,STRPTR Number)
  84. {
  85.     struct DialNode *Node;
  86.  
  87.     for(Node = (struct DialNode *)List->lh_Head ; Node->Node.ln_Succ ; Node = (struct DialNode *)Node->Node.ln_Succ)
  88.     {
  89.         if(!Stricmp(Node->Number,Number))
  90.             return(Node);
  91.     }
  92.  
  93.     return(NULL);
  94. }
  95.  
  96. STATIC STRPTR
  97. ExtractNextItem(STRPTR From,STRPTR To,LONG ToLen)
  98. {
  99.     if(From)
  100.     {
  101.         LONG i,Len,Start,NumberLen;
  102.  
  103.         Len = strlen(From);
  104.  
  105.         for(i = Start = 0 ; i < Len ; i++)
  106.         {
  107.             if(From[i] == '|' && From[i + 1] != '|')
  108.             {
  109.                 NumberLen = i - Start;
  110.  
  111.                 if(NumberLen > ToLen - 1)
  112.                     NumberLen = ToLen - 1;
  113.  
  114.                 if(NumberLen > 0)
  115.                     CopyMem(&From[Start],To,NumberLen);
  116.  
  117.                 To[NumberLen] = 0;
  118.  
  119.                 Start = i + 1;
  120.  
  121.                 while(Start < Len && From[Start] == '|')
  122.                     Start++;
  123.  
  124.                 if(Start == Len)
  125.                     return(NULL);
  126.                 else
  127.                     return(&From[Start]);
  128.             }
  129.         }
  130.  
  131.         /* No trailing bar? */
  132.  
  133.         if(Start >= Len)
  134.             To[0] = NULL;
  135.         else
  136.         {
  137.             NumberLen = Len - Start;
  138.  
  139.             if(NumberLen > ToLen - 1)
  140.                 NumberLen = ToLen - 1;
  141.  
  142.             if(NumberLen > 0)
  143.                 CopyMem(&From[Start],To,NumberLen);
  144.  
  145.             To[NumberLen] = 0;
  146.         }
  147.     }
  148.  
  149.     return(NULL);
  150. }
  151.  
  152. STATIC STRPTR
  153. CopyAndUpdate(STRPTR To,STRPTR From)
  154. {
  155.     LONG Len;
  156.  
  157.     Len = strlen(From) + 1;
  158.  
  159.     CopyMem(From,To,Len);
  160.  
  161.     return(To + Len);
  162. }
  163.  
  164. STATIC struct DialNode *
  165. CreateDialNode(PhoneEntry *Entry,STRPTR Number,STRPTR InitCommand,STRPTR ExitCommand,STRPTR DialPrefix,STRPTR DialSuffix)
  166. {
  167.     if(Number == NULL)
  168.         return(NULL);
  169.     else
  170.     {
  171.         struct DialNode *Node;
  172.         LONG Len;
  173.  
  174.         Len = strlen(Number) + 1;
  175.  
  176.         if(InitCommand)
  177.             Len += strlen(InitCommand) + 1;
  178.  
  179.         if(ExitCommand)
  180.             Len += strlen(ExitCommand) + 1;
  181.  
  182.         if(DialPrefix)
  183.             Len += strlen(DialPrefix) + 1;
  184.  
  185.         if(DialSuffix)
  186.             Len += strlen(DialSuffix) + 1;
  187.  
  188.         if(Node = (struct DialNode *)AllocVecPooled(sizeof(struct DialNode) + Len,MEMF_ANY|MEMF_CLEAR))
  189.         {
  190.             STRPTR String;
  191.  
  192.             String = (STRPTR)(Node + 1);
  193.  
  194.                 /* Set up the number */
  195.  
  196.             String = CopyAndUpdate(Node->Number = String,Number);
  197.  
  198.             if(InitCommand)
  199.                 String = CopyAndUpdate(Node->InitCommand = String,InitCommand);
  200.  
  201.             if(ExitCommand)
  202.                 String = CopyAndUpdate(Node->ExitCommand = String,ExitCommand);
  203.  
  204.             if(DialPrefix)
  205.                 String = CopyAndUpdate(Node->DialPrefix = String,DialPrefix);
  206.  
  207.             if(DialSuffix)
  208.                 CopyAndUpdate(Node->DialSuffix = String,DialSuffix);
  209.  
  210.                 /* Install the back link */
  211.  
  212.             Node->Entry = Entry;
  213.  
  214.             if(Entry == NULL)
  215.                 Node->Node.ln_Name = Node->Number;
  216.             else
  217.             {
  218.                 Node->Node.ln_Name = Entry->Header->Name;
  219.  
  220.                 if(!Entry->DialNode)
  221.                     Entry->DialNode = Node;
  222.             }
  223.  
  224.             Node->FromPhonebook = FALSE;
  225.         }
  226.  
  227.         return(Node);
  228.     }
  229. }
  230.  
  231. STATIC BOOL
  232. CreateDialNodes(struct List *List,PhoneEntry *Entry,STRPTR Number)
  233. {
  234.     if(Entry == NULL && Number == NULL)
  235.         return(FALSE);
  236.     else
  237.     {
  238.         UBYTE LocalNumberBuffer[256];
  239.         UBYTE LocalInitBuffer[80];
  240.         UBYTE LocalExitBuffer[80];
  241.         UBYTE LocalPrefixBuffer[80];
  242.         UBYTE LocalSuffixBuffer[80];
  243.         STRPTR NumberIndex,InitIndex,ExitIndex,PrefixIndex,SuffixIndex;
  244.  
  245.         if(Number)
  246.         {
  247.             NumberIndex = Number;
  248.  
  249.             InitIndex    = NULL;
  250.             ExitIndex    = NULL;
  251.             PrefixIndex    = NULL;
  252.             SuffixIndex    = NULL;
  253.         }
  254.         else
  255.         {
  256.             struct ModemSettings *ModemConfig;
  257.  
  258.             if(Entry->Config->ModemConfig)
  259.                 ModemConfig = Entry->Config->ModemConfig;
  260.             else
  261.                 ModemConfig = Config->ModemConfig;
  262.  
  263.             NumberIndex = Entry->Header->Number;
  264.  
  265.             InitIndex    = ModemConfig->ModemInit;
  266.             ExitIndex    = ModemConfig->ModemExit;
  267.             PrefixIndex    = ModemConfig->DialPrefix;
  268.             SuffixIndex    = ModemConfig->DialSuffix;
  269.         }
  270.  
  271.         do
  272.         {
  273.             if(Entry)
  274.             {
  275.                 if(InitIndex)
  276.                     InitIndex = ExtractNextItem(InitIndex,LocalInitBuffer,sizeof(LocalInitBuffer));
  277.  
  278.                 if(ExitIndex)
  279.                     ExitIndex = ExtractNextItem(ExitIndex,LocalExitBuffer,sizeof(LocalExitBuffer));
  280.  
  281.                 if(PrefixIndex)
  282.                     PrefixIndex = ExtractNextItem(PrefixIndex,LocalPrefixBuffer,sizeof(LocalPrefixBuffer));
  283.  
  284.                 if(SuffixIndex)
  285.                     SuffixIndex = ExtractNextItem(SuffixIndex,LocalSuffixBuffer,sizeof(LocalSuffixBuffer));
  286.             }
  287.  
  288.             NumberIndex = ExtractNextItem(NumberIndex,LocalNumberBuffer,sizeof(LocalNumberBuffer));
  289.  
  290.             if(LocalNumberBuffer[0])
  291.             {
  292.                 struct DialNode *Node;
  293.  
  294.                 if(Entry)
  295.                     Node = CreateDialNode(Entry,LocalNumberBuffer,LocalInitBuffer,LocalExitBuffer,LocalPrefixBuffer,LocalSuffixBuffer);
  296.                 else
  297.                     Node = CreateDialNode(Entry,LocalNumberBuffer,NULL,NULL,NULL,NULL);
  298.  
  299.                 if(Node)
  300.                     AddTail(List,(struct Node *)Node);
  301.                 else
  302.                     return(FALSE);
  303.             }
  304.         }
  305.         while(NumberIndex != NULL);
  306.  
  307.         return(TRUE);
  308.     }
  309. }
  310.  
  311. STATIC VOID
  312. AddDialEntryList(PhonebookHandle *PhoneHandle,struct List *List)
  313. {
  314.     if(PhoneHandle->DialList)
  315.     {
  316.         struct DialNode *Node,*OtherNode;
  317.  
  318.             /* Remove the dial nodes from the list and try to add them. */
  319.  
  320.         while(Node = (struct DialNode *)RemHead(List))
  321.         {
  322.                 /* Check if this number is already on the list. */
  323.  
  324.             if(OtherNode = FindNumberInDialList(PhoneHandle->DialList,Node->Number))
  325.             {
  326.                     /* A number without a phonebook entry attached will always lose. */
  327.  
  328.                 if(!OtherNode->Entry && Node->Entry)
  329.                 {
  330.                     RemoveDialNode(PhoneHandle,OtherNode);
  331.                     DeleteDialNode(OtherNode);
  332.                 }
  333.                 else
  334.                 {
  335.                     DeleteDialNode(Node);
  336.                     Node = NULL;
  337.                 }
  338.             }
  339.  
  340.                 /* Add the new list node. */
  341.  
  342.             if(Node != NULL)
  343.                 AddDialNode(PhoneHandle,Node);
  344.         }
  345.     }
  346. }
  347.  
  348. VOID
  349. ReattachDialNode(PhonebookHandle *PhoneHandle,PhoneEntry *Entry)
  350. {
  351.     if(PhoneHandle->DialList && Entry)
  352.     {
  353.         struct DialNode *Node;
  354.  
  355.         for(Node = (struct DialNode *)PhoneHandle->DialList->lh_Head ; Node->Node.ln_Succ ; Node = (struct DialNode *)Node->Node.ln_Succ)
  356.         {
  357.             if(Node->Entry == Entry && Node->Entry->DialNode == NULL)
  358.             {
  359.                 Node->Entry->DialNode = Node;
  360.                 break;
  361.             }
  362.         }
  363.     }
  364. }
  365.  
  366. VOID
  367. CleanseDialList(PhonebookHandle *PhoneHandle)
  368. {
  369.     if(PhoneHandle->DialList)
  370.     {
  371.         struct DialNode *Node,*Next;
  372.  
  373.         for(Node = (struct DialNode *)PhoneHandle->DialList->lh_Head ; Next = (struct DialNode *)Node->Node.ln_Succ ; Node = Next)
  374.         {
  375.             if(Node->Entry && Node->FromPhonebook)
  376.             {
  377.                 if(Node->Entry->Count < 0)
  378.                 {
  379.                     RemoveAndDeleteRelatedDialNodes(PhoneHandle,Node);
  380.  
  381.                     Next = (struct DialNode *)PhoneHandle->DialList->lh_Head;
  382.                 }
  383.             }
  384.         }
  385.     }
  386. }
  387.  
  388. struct DialNode *
  389. RemoveAndDeleteRelatedDialNodes(PhonebookHandle *PhoneHandle,struct DialNode *ThisNode)
  390. {
  391.     struct DialNode *NextNode;
  392.  
  393.     if(!PhoneHandle->DialList || !ThisNode)
  394.          NextNode = NULL;
  395.     else
  396.     {
  397.         struct DialNode *Node,*Next;
  398.         PhoneEntry *Entry;
  399.  
  400.         if(ThisNode->Node.ln_Succ->ln_Succ)
  401.             NextNode = (struct DialNode *)ThisNode->Node.ln_Succ;
  402.         else
  403.             NextNode = NULL;
  404.  
  405.         Entry = ThisNode->Entry;
  406.  
  407.         if(Entry)
  408.             Entry->DialNode = NULL;
  409.  
  410.         for(Node = (struct DialNode *)PhoneHandle->DialList->lh_Head ; Next = (struct DialNode *)Node->Node.ln_Succ ; Node = Next)
  411.         {
  412.             if(Node->Entry == Entry)
  413.             {
  414.                 if(Node == NextNode)
  415.                 {
  416.                     if(NextNode->Node.ln_Succ->ln_Succ)
  417.                         NextNode = (struct DialNode *)NextNode->Node.ln_Succ;
  418.                     else
  419.                         NextNode = NULL;
  420.                 }
  421.  
  422.                 RemoveDialNode(PhoneHandle,Node);
  423.                 DeleteDialNode(Node);
  424.             }
  425.         }
  426.     }
  427.  
  428.     return(NextNode);
  429. }
  430.  
  431. VOID
  432. DeleteDialNode(struct DialNode *SomeNode)
  433. {
  434.     if(SomeNode)
  435.     {
  436.         if(SomeNode->Entry && SomeNode->Entry->DialNode == SomeNode)
  437.             SomeNode->Entry->DialNode = NULL;
  438.  
  439.         FreeVecPooled(SomeNode);
  440.     }
  441. }
  442.  
  443. VOID
  444. RemoveDialNode(PhonebookHandle *PhoneHandle,struct DialNode *SomeNode)
  445. {
  446.         /* Do we have a dial list */
  447.  
  448.     if(PhoneHandle->DialList && SomeNode)
  449.     {
  450.             /* Remove all list entries that refer to the given phonebook entry */
  451.  
  452.         if(SomeNode->Entry && SomeNode->FromPhonebook)
  453.         {
  454.             UnmarkDialEntry(PhoneHandle,SomeNode->Entry);
  455.  
  456.             SomeNode->Entry->DialNode = NULL;
  457.         }
  458.  
  459.         Remove((struct Node *)SomeNode);
  460.  
  461.         if(SomeNode->FromPhonebook)
  462.         {
  463.             struct DialNode *Node;
  464.  
  465.             for(Node = (struct DialNode *)PhoneHandle->DialList->lh_Head ; Node->Node.ln_Succ ; Node = (struct DialNode *)Node->Node.ln_Succ)
  466.             {
  467.                 if(Node->FromPhonebook && Node->Entry == SomeNode->Entry)
  468.                 {
  469.                     Node->Entry->DialNode = Node;
  470.                     break;
  471.                 }
  472.             }
  473.         }
  474.     }
  475. }
  476.  
  477. BOOL
  478. AddDialNode(PhonebookHandle *PhoneHandle,struct DialNode *Node)
  479. {
  480.     if(!PhoneHandle->DialList)
  481.         PhoneHandle->DialList = CreateList();
  482.  
  483.     if(!PhoneHandle->DialList)
  484.         return(FALSE);
  485.     else
  486.     {
  487.         PhoneEntry *Entry;
  488.  
  489.             /* Does this entry have a list */
  490.  
  491.         if(Entry = Node->Entry)
  492.         {
  493.                 /* Has a list counter been assigned? */
  494.  
  495.             if(Entry->Count >= 0)
  496.             {
  497.                 struct DialNode *ListNode;
  498.                 LONG Count;
  499.  
  500.                     /* Walk down the dial list and find the place to put */
  501.                     /* the new entry */
  502.  
  503.                 for(ListNode = (struct DialNode *)PhoneHandle->DialList->lh_Head ; ListNode->Node.ln_Succ ; ListNode = (struct DialNode *)ListNode->Node.ln_Succ)
  504.                 {
  505.                         /* Insert the new entry in front of the first entry */
  506.                         /* with a larger index number or in front of an entry */
  507.                         /* that doesn't have a number assigned. */
  508.  
  509.                     Count = ListNode->Entry->Count;
  510.  
  511.                     if(Count < 0 || Count > Entry->Count)
  512.                     {
  513.                         Insert(PhoneHandle->DialList,(struct Node *)Node,ListNode->Node.ln_Pred);
  514.  
  515.                         return(TRUE);
  516.                     }
  517.                 }
  518.             }
  519.         }
  520.  
  521.             /* Add it to the end of the list */
  522.  
  523.         AddTail(PhoneHandle->DialList,(struct Node *)Node);
  524.  
  525.         return(TRUE);
  526.     }
  527. }
  528.  
  529. VOID
  530. DeleteDialList(PhonebookHandle *PhoneHandle)
  531. {
  532.     if(PhoneHandle->DialList)
  533.     {
  534.         struct DialNode *Node;
  535.  
  536.         for(Node = (struct DialNode *)PhoneHandle->DialList->lh_Head ; Node->Node.ln_Succ ; Node = (struct DialNode *)Node->Node.ln_Succ)
  537.         {
  538.             if(Node->Entry)
  539.                 Node->Entry->DialNode = NULL;
  540.         }
  541.  
  542.         DeleteList(PhoneHandle->DialList);
  543.         PhoneHandle->DialList = NULL;
  544.     }
  545. }
  546.  
  547.     /* AddDialEntry(PhonebookHandle *PhoneHandle,PhoneEntry *Entry,STRPTR Number):
  548.      *
  549.      *    Add a new entry to the dial list. Expand phone numbers separated by
  550.      *    vertical bars ("|") into several dial nodes. Eliminate duplicate
  551.      *    dial list entries.
  552.      */
  553.  
  554. BOOL
  555. AddDialEntry(PhonebookHandle *PhoneHandle,PhoneEntry *Entry,STRPTR Number)
  556. {
  557.     BOOL Result;
  558.  
  559.         /* Start from scratch. */
  560.  
  561.     Result = FALSE;
  562.  
  563.         /* If no dial list had been created before, create one now. */
  564.  
  565.     if(!PhoneHandle->DialList)
  566.         PhoneHandle->DialList = CreateList();
  567.  
  568.         /* Can we continue? */
  569.  
  570.     if(PhoneHandle->DialList && (Entry || Number))
  571.     {
  572.         struct List *LocalList;
  573.  
  574.             /* This is to keep the new list entries. */
  575.  
  576.         if(LocalList = CreateList())
  577.         {
  578.                 /* Create the dial list nodes corresponding
  579.                  * to the entry/phone number.
  580.                  */
  581.  
  582.             if(CreateDialNodes(LocalList,Entry,Number))
  583.             {
  584.                     /* Add the contents of the list to the dial list. */
  585.  
  586.                 AddDialEntryList(PhoneHandle,LocalList);
  587.  
  588.                     /* Everything went fine so far. */
  589.  
  590.                 Result = TRUE;
  591.             }
  592.  
  593.                 /* Delete the temporary list. */
  594.  
  595.             DeleteList(LocalList);
  596.         }
  597.     }
  598.  
  599.     return(Result);
  600. }
  601.  
  602. BOOL
  603. AddAllDialEntries(PhonebookHandle *PhoneHandle)
  604. {
  605.     BOOL Result;
  606.  
  607.         /* Start from scratch. */
  608.  
  609.     Result = FALSE;
  610.  
  611.         /* If no dial list had been created before, create one now. */
  612.  
  613.     if(!PhoneHandle->DialList)
  614.         PhoneHandle->DialList = CreateList();
  615.  
  616.         /* Can we continue? */
  617.  
  618.     if(PhoneHandle->DialList)
  619.     {
  620.         struct List *LocalList;
  621.  
  622.         if(LocalList = CreateList())
  623.         {
  624.             LONG i;
  625.  
  626.                 /* Add all tagged entries to the local list */
  627.  
  628.             for(i = 0 ; i < PhoneHandle->NumPhoneEntries ; i++)
  629.             {
  630.                 if(PhoneHandle->Phonebook[i]->Count >= 0)
  631.                 {
  632.                     if(!CreateDialNodes(LocalList,PhoneHandle->Phonebook[i],NULL))
  633.                     {
  634.                         DeleteList(LocalList);
  635.                         LocalList = NULL;
  636.  
  637.                         break;
  638.                     }
  639.                 }
  640.             }
  641.         }
  642.  
  643.             /* Check if we have a list to work with. */
  644.  
  645.         if(LocalList)
  646.         {
  647.             struct DialNode *Node;
  648.  
  649.                 /* Walk down the list, marking each entry as coming from the phonebook. */
  650.  
  651.             for(Node = (struct DialNode *)LocalList->lh_Head ; Node->Node.ln_Succ ; Node = (struct DialNode *)Node->Node.ln_Succ)
  652.                 Node->FromPhonebook = TRUE;
  653.  
  654.                 /* Add the contents of the list to the dial list. */
  655.  
  656.             AddDialEntryList(PhoneHandle,LocalList);
  657.  
  658.                 /* And delete what's left of the temporary list. */
  659.  
  660.             DeleteList(LocalList);
  661.  
  662.                 /* Everything went fine so far. */
  663.  
  664.             Result = TRUE;
  665.         }
  666.     }
  667.  
  668.     return(Result);
  669. }
  670.